﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
// add
using Microsoft.Win32;
using System.IO;
using System.Reflection;
using System.IO.Ports;
using System.Threading;
using Microsoft.VisualBasic;
using System.Diagnostics;

public enum enumRuntime { Production, Development, Testing }

namespace ConsoleBase
{
    public class CProject
    {
        public string msPathLastWork = string.Empty;
        public CAction mAction = new CAction();
        public enumRuntime mRuntime = enumRuntime.Production;

        static bool mbContinue;
        static Thread mThreadRead = new Thread(ThreadRead);

        // CFG file content:
        public string msFilenameCFG = string.Empty;
        static SerialPort mSP1;
        string msPortName;
        int miBaudRate;
        Parity mParity;
        int miDataBits;
        StopBits mStopBits;
        Handshake mHandshake;
        int mReadTimeout;
        int mWriteTimeout;


        // user.ini content
        //public string msUserMode;
        //public enumUserMode mUserMode;

        // mode.ini content
        public bool mbSelectProduct = false;
        public string msUtilityName;
        public string msModelName = string.Empty;

        public CProject()
        {
            mAction.Begin("CProject()");
            //ActionBegin("ShowFormOnlyOne()");
        }
        public string CompanyID { get { return "Champtek"; } }
        public string SystemID { get { return "BSCU"; } }
        public string ProjectID { get { return "BSCU1"; } }
        public bool IsDebug
        {
            get { return mAction.IsDebug; }
            set { mAction.IsDebug = value; }
        }
        public void DebugMsg(string sMsg)
        {
            if (IsDebug)
                mAction.DebugMsg(sMsg);
        }

        public bool End()
        {
            // add on
            if (IsDebug)
            {
                Properties.Settings.Default.Debug = 1;
                mAction.SaveLog();
            }
            else
                Properties.Settings.Default.Debug = 0;

            Properties.Settings.Default.Filename = msFilenameCFG;



            //Properties.Settings.Default.Save();
            SaveConfig();
            return true;
        }
        public void DefaultConfig()
        {
            msFilenameCFG = "NewFile";
            msPathLastWork = Environment.GetFolderPath(Environment.SpecialFolder.Personal);

        }
        public bool LoadConfig()
        {
            int i1;
            string sKey, sName, sValue;
            object oValue;

            mAction.DebugMsg("LoadConfig()");

            // Path test
            foreach (Environment.SpecialFolder v1 in Enum.GetValues(typeof(Environment.SpecialFolder)))
            {
                sValue = Environment.GetFolderPath(v1);
                sName = Enum.GetName(typeof(Environment.SpecialFolder), v1);
                mAction.DebugMsg(string.Format(sName + "=" + sValue));
            }
            //sValue = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
            //mAction.DebugMsg(string.Format(@"Environment.SpecialFolder.ApplicationData=" + sValue));
            //sValue = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
            //mAction.DebugMsg(string.Format(@"Environment.SpecialFolder.Personal=" + sValue));

            // Registry
            sKey = string.Format(@"HKEY_CURRENT_USER\Software\{0}\{1}\{2}", CompanyID, SystemID, ProjectID);
            sName = "PathPersonal";
            oValue = Registry.GetValue(sKey, sName, null);
            if (oValue == null)
                sValue = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
            else
                sValue = oValue.ToString();

            Registry.SetValue(sKey, sName, sValue);

            mAction.DebugMsg(string.Format(@"{0}\{1}={2}", sKey, sName, sValue));

            // Properties
            i1 = Properties.Settings.Default.Runtime;
            switch (i1)
            {
                case (int)enumRuntime.Development:
                    mRuntime = enumRuntime.Development;
                    break;

                case (int)enumRuntime.Testing:
                    mRuntime = enumRuntime.Testing;
                    break;
                default:
                    mRuntime = enumRuntime.Production;
                    break;
            }


            i1 = Properties.Settings.Default.Debug;
            if (i1 == 1)
                IsDebug = true;
            else
                IsDebug = false;


            msFilenameCFG = Properties.Settings.Default.Filename;
            msPathLastWork = Properties.Settings.Default.PathLastWork;

            return true;
        }
        public bool SaveConfig()
        {
            Properties.Settings.Default.Save();
            return true;
        }
        public bool Begin()
        {
            DefaultConfig();

            if (!LoadConfig())
                return false;

            return true;
        }
        public bool MainFunction(string[] args)
        {
            int i1;
            string s1;

            ShowMsg("MainFunction()");
            msPortName = Properties.Settings.Default.PortName;
            miBaudRate = Properties.Settings.Default.BaudRate;
            if (mySetParity() == false)
                return false;

            if (mySetStopBits() == false)
                return false;

            miDataBits = Properties.Settings.Default.DataBits;
            if (mySetHandshake() == false)
                return false;

            mReadTimeout = Properties.Settings.Default.ReadTimeout;
            mWriteTimeout = Properties.Settings.Default.WriteTimeout;

            msFilenameCFG = Properties.Settings.Default.Filename;


            // Allow the user to set the appropriate properties.
            mSP1 = new SerialPort();
            mSP1.PortName = msPortName;
            mSP1.BaudRate = miBaudRate;
            mSP1.Parity = mParity;
            mSP1.DataBits = miDataBits;
            mSP1.StopBits = mStopBits;
            mSP1.Handshake = mHandshake;

            // Set the read/write timeouts
            mSP1.ReadTimeout = 500;
            mSP1.WriteTimeout = 500;
            try
            {
                mSP1.Open();
            }
            catch (Exception ex)
            {   
                ShowMsg(string.Format("Exception: Open(), {0}.", ex.Message));
                return false;
            }
            mbContinue = true;
            mThreadRead.Start();
            ShowMsg("MainFunction()");
            //Console.Write(". ");
            //s1 = Console.ReadLine();

            //Console.WriteLine("Type QUIT to exit");
            while (mbContinue)
            {
                Console.WriteLine(@"1 Notepad c:\tmep\test1.txt");
                Console.WriteLine("or Type QUIT to exit");
                Console.Write(". ");
                s1 = Console.ReadLine();

                if (string.Compare("quit", s1, true) == 0)
                {
                    mbContinue = false;
                    continue;
                }
                else if (string.Compare("1", s1, true) == 0)
                {
                    //Process.Start("shutdown", "/s /t 0");
                    Process.Start("Notepad", @"c:\temp\test1.txt");
                }
            }

            mThreadRead.Join();
            mSP1.Close();

            return true;
        }
        bool mySetParity()
        {
            string s1;
            object o1;

            s1 = Properties.Settings.Default.Parity;
            o1 = Enum.Parse(typeof(Parity), s1);
            if (o1 == null)
            {
                Console.WriteLine(string.Format("Wrong parity = {0}. Available options:", s1));
                foreach (string s in Enum.GetNames(typeof(Parity)))
                {
                    Console.WriteLine("   {0}", s);
                }
                return false;
            }
            mParity = (Parity)o1;
            return true;
        }
        bool mySetHandshake()
        {
            string s1;
            object o1;

            s1 = Properties.Settings.Default.Handshake;
            o1 = Enum.Parse(typeof(Handshake), s1);
            if (o1 == null)
            {
                Console.WriteLine(string.Format("Wrong handshake = {0}. Available options:", s1));
                foreach (string s in Enum.GetNames(typeof(Handshake)))
                {
                    Console.WriteLine("   {0}", s);
                }
                return false;
            }
            mHandshake = (Handshake)o1;
            return true;
        }
        bool mySetStopBits()
        {
            int i1;
            object o1;

            i1 = Properties.Settings.Default.StopBits;
            if (i1 == 0)
                mStopBits = StopBits.None;
            else
                mStopBits = StopBits.One;

            return true;
        }
        public string AssemblyTitle
        {
            get
            {
                object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), false);
                if (attributes.Length > 0)
                {
                    AssemblyTitleAttribute titleAttribute = (AssemblyTitleAttribute)attributes[0];
                    if (titleAttribute.Title != "")
                    {
                        return titleAttribute.Title;
                    }
                }
                return System.IO.Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().CodeBase);
            }
        }

        public string AssemblyVersion
        {
            get
            {
                return Assembly.GetExecutingAssembly().GetName().Version.ToString();
            }
        }

        public string ProductName
        {
            get { return AssemblyTitle; }
        }
        public string ProductVersion
        {
            get { return AssemblyVersion; }
        }
        public void PopupMsg(string sMsg)
        {
            DebugMsg(sMsg);
            //MessageBox.Show(sMsg, ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
            Console.WriteLine(sMsg);
            Console.ReadKey(false);
        }
        public void ShowMsg(string sMsg)
        {
            DebugMsg(sMsg);
            //MessageBox.Show(sMsg, ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
            Console.WriteLine(sMsg);
            //Console.ReadKey(false);
        }
        public void PopupError(string sMsg)
        {
            DebugMsg(sMsg);
            //MessageBox.Show(sMsg, ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
            Console.WriteLine(sMsg);
            Console.ReadKey(false);
        }
        public bool AskMsg(string sMsg)
        {
            ConsoleKeyInfo kInput;
            string sInput;
            DebugMsg(sMsg);
            Console.WriteLine(sMsg);
            Console.WriteLine("Y/N ?");
            kInput = Console.ReadKey(true);
            sInput = kInput.KeyChar.ToString();
            if (string.Compare(sInput, "Y", true) == 0)
                return true;
            else
                return false;
        }

        public string ByteArrayToHex(byte[] ba1)
        {
            // code helper:
            // byte[] data = { 1, 2, 4, 8, 16, 32 };
            // string hex = BitConverter.ToString(data);
            // hex = 01-02-04-08-10-20
            // string hex = BitConverter.ToString(data).Replace("-", string.Empty);
            // hex = 010204081020
            return BitConverter.ToString(ba1).Replace("-", string.Empty);
        }
        public string ByteToHex(byte b1)
        {
            // Example: Input 10, output "A".
            return string.Format("{0:X}", b1);
        }
        public byte HexToByte(string sHex)
        {
            // example: input "A", return 10.
            return byte.Parse(sHex, System.Globalization.NumberStyles.AllowHexSpecifier);
        }


        public int GetASCValue(char cUTF8)
        {
            return (System.Text.Encoding.UTF8.GetBytes(new char[] { cUTF8 }))[0];
        }
        public byte[] GetASCValues(string sUTF8)
        {
            return (System.Text.Encoding.UTF8.GetBytes(sUTF8));
        }
        public char GetAscChar(int iAsc)
        {
            // char c1 = '\u0001';
            // char c1 = (char) 1;
            return (char)iAsc;
        }
        public byte XOR(byte b1, byte b2)
        {
            // code helper
            return Convert.ToByte(b1 ^ b2);
            //bXOR = 0;
            //for (int i = 1; i < 262; i++)
            //    bXOR = (byte)(bXOR ^ e.Data[i]);

        }
        public long GetDateTimeLong(DateTime dt)
        {
            return long.Parse(dt.ToString("yyyyMMddHHmmssfff"));
        }

        public string LeftString(string sInput, int iLen)
        {
            int iMyLen;
            if (string.IsNullOrEmpty(sInput))
                return string.Empty;

            if (iLen > sInput.Length)
                iMyLen = sInput.Length;
            else
                iMyLen = iLen;

            return sInput.Substring(0, iMyLen);
        }
        public string RightString(string sInput, int iLen)
        {
            int iMyLen;
            if (string.IsNullOrEmpty(sInput))
                return string.Empty;

            if (iLen > sInput.Length)
                iMyLen = sInput.Length;
            else
                iMyLen = iLen;

            return sInput.Substring(sInput.Length - iMyLen, iMyLen);
        }
        public static void ThreadRead()
        {
            while (mbContinue)
            {
                try
                {
                    string message = mSP1.ReadLine();
                    Console.WriteLine(message);
                }
                catch (TimeoutException) { }
            }
        }
    }
}
